package ar.com.spsolutions.splilabrary.view.pages.book.gbook;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import ar.com.spsolutions.splibrary.book.Book;
import ar.com.spsolutions.splilabrary.view.version2.components.MainContainer;

public class GoogleBookDischargerComponent extends MainContainer implements
		IHeaderContributor {

	private static final long serialVersionUID = -5216471520841257974L;

	@SpringBean
	private GoogleBookFinder googleBookFinder;

	private String query;

	private AjaxFallbackDefaultDataTable<Book> resultTable;

	@Override
	protected void addComponents() {
		final Form<GoogleBookDischargerComponent> form = new Form<GoogleBookDischargerComponent>(
				"searchForm",
				new CompoundPropertyModel<GoogleBookDischargerComponent>(this));
		form.add(new RequiredTextField<String>("query"));
		this.resultTable = this.createResultTable();
		this.add(this.resultTable);
		this.resultTable.setOutputMarkupId(true);
		this.setOutputMarkupPlaceholderTag(true);
		form.add(this.getSearchButton(this.getFeedbackPanel(), this.resultTable));
		this.add(form);
	}

	private AjaxFallbackDefaultDataTable<Book> createResultTable() {
		final List<IColumn<Book>> columns = this.getColumns();
		final ISortableDataProvider<Book> dataProvider = this.getDataProvider();
		return new AjaxFallbackDefaultDataTable<Book>("resultTable", columns,
				dataProvider, 5);
	}

	private List<IColumn<Book>> getColumns() {
		final List<IColumn<Book>> columns = new ArrayList<IColumn<Book>>();
		columns.add(new AbstractColumn<Book>(new ResourceModel("table.pic")) {

			private static final long serialVersionUID = -343490172658176761L;

			@Override
			public void populateItem(final Item<ICellPopulator<Book>> cellItem,
					final String componentId, final IModel<Book> rowModel) {
				cellItem.add(new Label(componentId, new ImgModel(rowModel))
						.setOutputMarkupId(true));

			}

		});
		columns.add(new PropertyColumn<Book>(new ResourceModel("table.title"),
				"title", "title"));
		columns.add(new PropertyColumn<Book>(new ResourceModel("table.author"),
				"author", "author.name"));
		columns.add(new PropertyColumn<Book>(new ResourceModel("table.isbn"),
				"isbn", "isbn"));
		columns.add(new AbstractColumn<Book>(new ResourceModel("table.action")) {

			private static final long serialVersionUID = -5122306404366954837L;

			@Override
			public void populateItem(final Item<ICellPopulator<Book>> cellItem,
					final String componentId, final IModel<Book> rowModel) {
				cellItem.add(new AjaxLink<Book>(componentId, rowModel) {

					private static final long serialVersionUID = 4315926271868852327L;

					@Override
					public void onClick(final AjaxRequestTarget target) {
						GoogleBookDischargerComponent.this
								.getGoogleBookFinder()
								.add(rowModel.getObject());
						this.setResponsePage(this.getPage());
					}

				});
			}
		});
		return columns;
	}

	private ISortableDataProvider<Book> getDataProvider() {
		return new SortableDataProvider<Book>() {

			private static final long serialVersionUID = 1286629346799554176L;

			@Override
			public Iterator<? extends Book> iterator(final int first,
					final int count) {
				return GoogleBookDischargerComponent.this.getGoogleBookFinder()
						.iterator(first, count);
			}

			@Override
			public int size() {
				return GoogleBookDischargerComponent.this.getGoogleBookFinder()
						.size();
			}

			@Override
			public IModel<Book> model(final Book object) {
				return new CompoundPropertyModel<Book>(object);
			}
		};
	}

	private AjaxSubmitLink getSearchButton(final FeedbackPanel feedbackPanel,
			final AjaxFallbackDefaultDataTable<Book> table) {
		final AjaxSubmitLink searchButton = new AjaxSubmitLink("searchButton") {

			private static final long serialVersionUID = -4706360270006541242L;

			@Override
			protected void onSubmit(final AjaxRequestTarget target,
					final Form<?> form) {
				final GoogleBookDischargerComponent thiss = GoogleBookDischargerComponent.this;
				thiss.getGoogleBookFinder().search(thiss.getQuery());
				table.modelChanged();
				target.add(feedbackPanel);
				target.add(table);
			}

			@Override
			protected void onError(final AjaxRequestTarget target,
					final Form<?> form) {
				target.add(feedbackPanel);
			}
		};
		return searchButton;
	}

	// -- accessors --
	public GoogleBookFinder getGoogleBookFinder() {
		return this.googleBookFinder;
	}

	public void setGoogleBookFinder(final GoogleBookFinder googleBookFinder) {
		this.googleBookFinder = googleBookFinder;
	}

	public String getQuery() {
		return this.query;
	}

	public void setQuery(final String query) {
		this.query = query;
	}

	public AjaxFallbackDefaultDataTable<Book> getResultTable() {
		return this.resultTable;
	}

	public void setResultTable(
			final AjaxFallbackDefaultDataTable<Book> resultTable) {
		this.resultTable = resultTable;
	}

}

class ImgModel implements IModel<Image> {

	private static final long serialVersionUID = -1181372159575033902L;

	private final String bookImg;

	public ImgModel(final IModel<Book> rowModel) {
		this.bookImg = rowModel.getObject().getPic();
	}

	@Override
	public void detach() {
		// throw new UnsupportedOperationException();
	}

	@Override
	public Image getObject() {
		return new Image("pic", this.bookImg);
	}

	@Override
	public void setObject(final Image object) {
		throw new UnsupportedOperationException();
	}

}
